package junior.db.dao.mybatis.type;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ResultType<T> {
    private Class<T> type;
    private List<AssociationType> associationTypes;
    
    public static <E> ResultType<E> of(Class<E> type) {
        return new ResultType<E>(type);
    }
    
    public ResultType(Class<T> type) {
        this.type = type;
    }
    
    /**
     * 设置结果集中的关联类型，一对一或多对一的场景
     * @param field 关联类型在结果集中的字段名
     * @param associateType 关联类型
     * @param columnMapping 列映射，Map<字段名，列名>，可为null，当返回字段名与类型中字段名不一致时必须配置
     * @return
     */
    public ResultType nestObject(String field, Class<?> associateType, @Nullable Map<String, String> columnMapping) {
        if (associationTypes == null) {
            associationTypes = new ArrayList<>();
        }
        associationTypes.add(new AssociationType(field, associateType, columnMapping));
        return this;
    }
    
    /**
     * 设置结果集中的集合关联类型，一对多或多对多的场景
     * @param collectionField 集合关联类型在结果集中的字段名
     * @param collectionType 集合关联类型
     * @param componentType 集合关联类型中的元素类型
     * @param columnMapping 列映射，Map<字段名，列名>，可为null，当返回字段名与类型中字段名不一致时必须配置
     * @return
     */
    public ResultType nestCollection(String collectionField, Class<?> collectionType, Class<?> componentType, @Nullable Map<String, String> columnMapping) {
        if (associationTypes == null) {
            associationTypes = new ArrayList<>();
        }
        associationTypes.add(new AssociationType(collectionField, collectionType, componentType, columnMapping));
        return this;
    }
    
    public Class<T> getType() {
        return type;
    }
    
    public List<AssociationType> getAssociationTypes() {
        return associationTypes;
    }
}
